#ifndef PM_TASK_HISTORY_H_INCLUDED
#define PM_TASK_HISTORY_H_INCLUDED

#include "pm/task.h"
#include "pm/criteria.h"

namespace pm {

/**
 * \class TaskHistory
 */
class TaskHistory
{
	Task m_task;
	wxDateTime m_updateDate;
	
public:
	TaskHistory();
	TaskHistory(wxSQLite3ResultSet& res);
	
	db::ID id() const { return m_task.id(); }
	const wxString& name() const { return m_task.name(); }
	double unit_cost() const { return m_task.unit_cost(); }
	double quantity() const { return m_task.quantity(); }
	double cost() const { return m_task.cost(); }
	const wxDateTime& end_date() const { return m_task.end_date(); }
	const wxDateTime& update_date() const { return m_updateDate; }
	bool finished() const { return m_task.finished(); }
};

/**
 * \class GetTaskHistory
 */
struct GetTaskHistory : public ICriteriaForEach<TaskHistory>
{
	db::ID          m_idProject;

	GetTaskHistory(db::ID idProject);
};


/**
 * \class GetTaskHistoryByProject
 */
struct GetTaskHistoryByProject : public GetTaskHistory
{
	static const char* QUERY;

	GetTaskHistoryByProject(db::ID idProject);
	
	virtual wxSQLite3Statement prepare(wxSQLite3Database& db);
};

/**
 * GetTaskHistoryByTask
 */
struct GetTaskHistoryByTask : public GetTaskHistory
{
	db::ID m_idTask;

	static const char* QUERY;

	GetTaskHistoryByTask(db::ID idProject, db::ID idTask);
	
	virtual wxSQLite3Statement prepare(wxSQLite3Database& db);
};


/**
 * \class TaskAndCost
 */
struct TaskAndCost
{
	TaskHistory   m_task;
	double        m_costDone;
	
	TaskAndCost(wxSQLite3ResultSet& res)
	: m_task(res)
	, m_costDone(res.GetDouble(wxT("cost_done"), 0.0))
	{
	}
	
	db::ID id() const { return m_task.id(); }
	const wxString& name() const { return m_task.name(); }
	double unit_cost() const { return m_task.unit_cost(); }
	double quantity() const { return m_task.quantity(); }
	double cost() const { return m_task.cost(); }
	const wxDateTime& end_date() const { return m_task.end_date(); }
	const wxDateTime& update_date() const { return m_task.update_date(); }
	double cost_done() const { return m_costDone; }
	double total_cost() const { return m_costDone + m_task.cost(); }
	bool finished() const { return m_task.finished(); }
};

/**
 * \class TaskVsInitial
 */
class TaskVsInitial
{
	db::ID   m_idTask;
	wxString m_name;
	double   m_todo;
	double   m_done;
	double   m_initial;
	
public:
	TaskVsInitial(wxSQLite3ResultSet& res);
	
	db::ID id_task() const { return m_idTask; }
	const wxString& name() const { return m_name; }
	double todo() const { return m_todo; }
	double done() const { return m_done; }
	double initial() const { return m_initial; }
	double total() const { return m_todo + m_done; }
	double difference() const { return m_initial - total(); }
};

/**
 * GetTaskHistoryByDate
 */
struct GetTaskHistoryByDate : public ICriteriaForEach<TaskAndCost>
{
	db::ID          m_idProject;
	wxDateTime      m_date;

	static const char* QUERY;

	GetTaskHistoryByDate(db::ID idProject, const wxDateTime& date);
	
	virtual wxSQLite3Statement prepare(wxSQLite3Database& db);
};

/**
 * GetTasksVsInitial
 */
struct GetTasksVsInitial : public ICriteriaForEach<TaskVsInitial>
{
	db::ID m_idProject;
	
	GetTasksVsInitial(db::ID idProject);
	
	virtual wxSQLite3Statement prepare(wxSQLite3Database& db);
};

/**
 * \class CreateInitialTaskHistory
 */
struct CreateInitialTaskHistory : public ICriteria
{
	Task m_task;
	
	CreateInitialTaskHistory(const Task& task);
	
	virtual bool query(wxSQLite3Database& db);
};

} // namespace pm

#endif // PM_TASK_HISTORY_H_INCLUDED
